/*
 * @Description: 线路规划入口页
 * @Author: jun.fu
 * @Date: 2019-03-07 17:37:39
 * @Last Modified by:   jun.fu
 * @Last Modified time: 2019-03-07 17:37:39
 */
import React, { Component } from 'react'
import {
  StyleSheet,
  Text,
  View,
  ScrollView,
  TouchableOpacity,
  Image
} from 'react-native'
import StartAndEndPosition from '../components/RoutePlan/components/StartAndEndPosition'
import { px2dp, showToast } from 'rn-xiaobu-utils'
import Icon from '../components/public/icon'
import { iconDefaultColor } from '../configs/skin'
import fontsize from '../configs/fontsize'
import AddressSave from '../components/RoutePlan/components/AddressSave'
import AddressSaveInfo from '../components/RoutePlan/models/AddressSaveInfo'
import Loading from '../components/public/loading'
import flexStyle from '../configs/flex'
import { getCurrentPosition } from '../../plugins/location'
import SearchHistoryItem from '../components/RoutePlan/components/SearchHistoryItem'
import { defaultStackOptions } from '../utils/DefaultTitleOption'
import XiaobuStorage from '../utils/XiaobuStorage'
import { routePlanPositionCache } from '../components/public/confs/StorageKeys';

export default class RoutePlanEntrance extends Component {
  static navigationOptions = ({ navigation }) => {
    let option = defaultStackOptions({ navigation })
    option.headerTitle = '线路规划'
    option.headerRight = (
      <TouchableOpacity
        style={{ paddingRight: px2dp(30) }}
        onPress={navigation.getParam('search')}
      >
        <Text style={{ color: iconDefaultColor }}>搜索</Text>
      </TouchableOpacity>
    )
    return option
  }

  state = {
    saveAddressList: [],
    searchHistoryList: [],
    showSetting: false,
    startPositionName: '输入出发地',
    endPositionName: '输入目的地'
  }

  readyToChangeAddress = undefined // 准备更改的存储的站点
  startPosition = undefined // 起始站点
  endPosition = undefined // 终末站点
  SAVEADDRESSKEY = 'routePlanEntranceSaveAddress123124498' // 缓存中保存用户收藏站点的key
  SEARCHHISTORYKEY = 'routePlanEntranceSearchHistory092389432' // 缓存中存储的搜索历史的key

  componentDidMount () {
    // 设置右上角搜索按钮函数
    this.props.navigation.setParams({ search: this.search })
    // 获取当前位置信息，并设置到起始站点
    getCurrentPosition().then(res => {
      this.setStartPosition(res)
    })
    // 获取缓存中用户收藏的站点信息，没有则初始化
    XiaobuStorage.getItem(this.SAVEADDRESSKEY)
      .then(res => {
        if (res) {
          this.changeSaveAddressList(JSON.parse(res))
        } else {
          this.initSaveAddressList()
        }
      })
      .catch(() => {
        this.initSaveAddressList()
      })
    // 获取缓存中的搜索历史
    XiaobuStorage.getItem(this.SEARCHHISTORYKEY).then(res => {
      if (res) {
        this.setState({
          searchHistoryList: JSON.parse(res)
        })
      }
    })
  }

  /**
   * 初始化用户收藏的站点信息
   */
  initSaveAddressList = () => {
    let list = []
    list.push(new AddressSaveInfo('0', '', '', '', '回家', 1))
    list.push(new AddressSaveInfo('1', '', '', '', '上班', 2))
    this.changeSaveAddressList(list)
  }

  /**
   * 设置起始站点信息
   * @param {String} id 标识符
   * @param {String} name 名称
   * @param {String} lat 经度
   * @param {String} lng 纬度
   */
  setStartPosition = ({ id, name, lat, lng } = {}) => {
    this.setState({
      startPositionName: name
    })
    this.startPosition = {
      id,
      name,
      lat,
      lng
    }
  }

  /**
   * 设置终末站点信息
   * @param {String} id 标识符
   * @param {String} name 名称
   * @param {String} lat 经度
   * @param {String} lng 纬度
   */
  setEndPosition = ({ id, name, lat, lng } = {}) => {
    this.setState({
      endPositionName: name
    })
    this.endPosition = {
      id,
      name,
      lat,
      lng
    }
  }

  /**
   * 搜索函数
   */
  search = () => {
    // 无起始站点
    if (
      !this.startPosition ||
      (!this.startPosition.lat || !this.startPosition.lng)
    ) {
      showToast('请输入起点')
      return
    }
    // 无终末站点
    if (!this.endPosition || (!this.endPosition.lat || !this.endPosition.lng)) {
      showToast('请输入终点')
      return
    }
    this.goToRoutePlan(this.startPosition, this.endPosition)
  }

  /**
   * 跳转到线路规划页
   * @param {{id,name,lat,lng}} start 起始站点
   * @param {{id,name,lat,lng}} end 终末站点
   */
  goToRoutePlan = (start, end) => {
    this.props.navigation.navigate('RoutePlan', {
      start,
      end
    })
    // 存储到搜索历史中
    let history = this.state.searchHistoryList
    let flag = false
    for (let item of history) {
      if (item.start.name === start.name && item.end.name === end.name) {
        flag = true
        break
      }
    }
    if (!flag) {
      history.push({ start, end })
    }
    this.setState({
      searchHistoryList: history
    })
    XiaobuStorage.setItem(this.SEARCHHISTORYKEY, JSON.stringify(history))
  }

  /**
   * 清除搜索历史
   */
  cleanSearchHistory = () => {
    this.setState({
      searchHistoryList: []
    })
    XiaobuStorage.removeItem(this.SEARCHHISTORYKEY)
  }

  /**
   * 跳转到查询站点页
   * @param {Function} callback 获取到站点后的回调函数
   */
  goToSearchDetails = callback => {
    this.props.navigation.push('SearchDetails', {
      type: 3,
      shouldBack: true,
      needMyPosition: true,
      getInfo: callback,
      cacheKey: routePlanPositionCache
    })
  }

  /**
   * 更改用户收藏的站点信息列表
   * @param {Array} list
   */
  changeSaveAddressList = list => {
    this.setState({
      saveAddressList: list
    })
    XiaobuStorage.setItem(this.SAVEADDRESSKEY, JSON.stringify(list))
  }

  /**
   * 交换起末站点
   */
  switchStartAndEnd = () => {
    let startPosition = this.startPosition
    let endPosition = this.endPosition
    this.setStartPosition(endPosition)
    this.setEndPosition(startPosition)
  }

  /**
   * 更改起始站点后的回调函数
   * @param {Object} info 更改的站点信息
   */
  changeStartPositionCallBack = info => {
    if (!this.endPosition || (
      info.lat !== this.endPosition.lat ||
      info.lng !== this.endPosition.lng
    )
    ) {
      this.setStartPosition(info)
      return
    }
    showToast('起终点不能相同')
  }

  /**
   * 更改终末站点后的回调函数
   * @param {Object} info 更改的站点信息
   */
  changeEndPositionCallBack = info => {
    if (!this.startPosition || (
      info.lat !== this.startPosition.lat ||
      info.lng !== this.startPosition.lng)
    ) {
      this.setEndPosition(info)
    }
    showToast('起终点不能相同')
  }

  /**
   * 用户收藏的站点信息右边的设置按钮
   * @param {key,value:{id,name,lat,lng,alias,sort}} info 站点信息
   */
  setting = info => {
    // 保存站点信息，供修改调用
    this.readyToChangeAddress = info
    this.setState({
      showSetting: true
    })
  }

  /**
   * 关闭设置按钮
   */
  closeSetting = () => {
    this.setState(
      {
        showSetting: false
      },
      () => {
        this.readyToChangeAddress = undefined
      }
    )
  }

  /**
   * 收藏新的站点信息回调
   * @param {{id,name,lat,lng}} info 站点信息
   */
  addAddressCallBack = info => {
    let list = this.state.saveAddressList
    list.push(new AddressSaveInfo(info.id, info.name, info.lat, info.lng, ''))
    this.changeSaveAddressList(list)
  }

  /**
   * 删除收藏的站点信息
   */
  deleteAddress = () => {
    let info = this.readyToChangeAddress
    let list = this.state.saveAddressList
    if (info.value.sort !== 1 && info.value.sort !== 2) {
      // 如果是普通站点，则清除
      list.splice(info.key, 1)
    } else {
      // 如果是回家或者公司，则还原为空的回家或公司对象
      list.splice(
        info.key,
        1,
        new AddressSaveInfo(
          info.value.id,
          '',
          '',
          '',
          info.value.alias,
          info.value.sort
        )
      )
    }
    this.changeSaveAddressList(list)
    this.closeSetting()
  }

  /**
   * 重新设置收藏的站点信息回调
   * @param {{id,name,lat,lng}} info 站点信息
   */
  resetAddressCallBack = info => {
    console.log(info)
    let originInfo = this.readyToChangeAddress
    let list = this.state.saveAddressList
    // 替换
    list.splice(originInfo.key, 1, Object.assign(originInfo.value, info))
    // 重新存储
    this.changeSaveAddressList(list)
    this.closeSetting()
  }

  /**
   * 点击收藏站点时，跳转到线路规划页
   * @param info
   */
  routeToSaveAddress = info => {
    if (info.value.lat && info.value.lng) {
      // 如果点击的收藏站点有经纬度，则获取当前位置并跳转到线路规划页
      getCurrentPosition().then(res => {
        this.goToRoutePlan(res, info.value)
      })
    } else {
      // 如果点击的收藏站点没有经纬度，则进入更改收藏站点信息逻辑
      this.readyToChangeAddress = info
      this.goToSearchDetails(this.resetAddressCallBack)
    }
  }

  /**
   * 前往收藏别名更改页面
   */
  gotoAddSearchName = () =>{
    this.props.navigation.navigate('AddSearchName', {
      change: text =>{
        if (text) {
          // 重置别名
          this.resetAddressCallBack({ alias: text })
        } else {
          this.resetAddressCallBack({})
        }
      }
    })
  }

  /**
   * 渲染用户收藏站点列表
   * @returns {*[]}
   */
  renderSaveAddressList = () => {
    return this.state.saveAddressList.map((element, index) => (
      <AddressSave
        {...element}
        key={index}
        index={index}
        setting={this.setting}
        onPress={this.routeToSaveAddress}
      />
    ))
  }

  /**
   * 渲染设置模块
   * @returns {*}
   */
  renderSetting = () => {
    return (
      <View style={styles.setting}>
        <TouchableOpacity
          style={[
            styles.settingItem,
            fontsize.fontsize28,
            flexStyle.flexH,
            flexStyle.flexVc
          ]}
          activeOpacity={0.8}
          onPress={
            this.gotoAddSearchName}
        >
          <Icon name={'write'} size={30}
            style={styles.settingItemIcon}/>
          <Text>自定义名称</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[
            styles.settingItem,
            fontsize.fontsize28,
            flexStyle.flexH,
            flexStyle.flexVc
          ]}
          activeOpacity={0.8}
          onPress={() => {
            this.goToSearchDetails(this.resetAddressCallBack)
          }}
        >
          <Icon name={'place'} size={30}
            style={styles.settingItemIcon}/>
          <Text>重新设置地址</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[
            styles.settingItem,
            fontsize.fontsize28,
            flexStyle.flexH,
            flexStyle.flexVc
          ]}
          activeOpacity={0.8}
          onPress={this.deleteAddress}
        >
          <Icon name={'delete'} size={30}
            style={styles.settingItemIcon}/>
          <Text>删除地址</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[
            styles.settingItem,
            { marginTop: px2dp(16) },
            fontsize.fontsize28,
            flexStyle.flexH,
            flexStyle.flexVc,
            flexStyle.flexHc
          ]}
          activeOpacity={0.8}
          onPress={this.closeSetting}
        >
          <Text>取消</Text>
        </TouchableOpacity>
      </View>
    )
  }

  /**
   * 渲染搜索历史列表
   * @returns {*[]}
   */
  renderSearchHistory = () => {
    return this.state.searchHistoryList.map((element, index) => (
      <SearchHistoryItem start={element.start} end={element.end}
        key={index}/>
    ))
  }

  render () {
    return (
      <View style={styles.container}>
        {/* 设置模块是否展示判定 */}
        {this.state.showSetting ? (
          <Loading
            children={this.renderSetting()}
            onPress={this.closeSetting}
          />
        ) : null}
        <View style={styles.startAndEnd}>
          {/* 起末站点选择器 */}
          <StartAndEndPosition
            startName={this.state.startPositionName}
            endName={this.state.endPositionName}
            switch={this.switchStartAndEnd}
            changeStartStation={() => {
              this.goToSearchDetails(this.changeStartPositionCallBack)
            }}
            changeEndStation={() => {
              this.goToSearchDetails(this.changeEndPositionCallBack)
            }}
          />
        </View>
        {/* 收藏站点列表和搜索历史列表展示 */}
        <ScrollView style={{ flex: 1, zIndex: 2 }}>
          {this.renderSaveAddressList()}
          {/* 添加新的收藏按钮 */}
          <TouchableOpacity
            onPress={() => {
              this.goToSearchDetails(this.addAddressCallBack)
            }}
          >
            <Text style={[styles.addAddress, fontsize.fontsize28]}>
              <Icon name={'add'} size={24}/>
              &nbsp;添加地点
            </Text>
          </TouchableOpacity>
          <Text style={[styles.historyTitle, fontsize.fontsize24]}>
            搜索历史
          </Text>
          {this.renderSearchHistory()}
          {/* 清除搜索历史记录按钮展示判定 */}
          {this.state.searchHistoryList.length > 0 ? (
            <TouchableOpacity onPress={this.cleanSearchHistory}>
              <Text
                style={[
                  styles.addAddress,
                  { color: '#999999' },
                  fontsize.fontsize28
                ]}
              >
                清除历史记录
              </Text>
            </TouchableOpacity>
          ) : null}
        </ScrollView>
        {/* 背景图片 */}
        <Image
          style={{
            width: '100%',
            height: px2dp(360),
            position: 'absolute',
            bottom: 0,
            zIndex: 1
          }}
          source={require('../../assets/img/background.png')}
        />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F2F5F6'
  },
  startAndEnd: {
    height: px2dp(281),
    paddingTop: px2dp(40),
    paddingBottom: px2dp(40),
    backgroundColor: '#ffffff',
    marginBottom: px2dp(16)
  },
  addAddress: {
    backgroundColor: '#FFFFFF',
    color: iconDefaultColor,
    textAlign: 'center',
    height: px2dp(100),
    lineHeight: px2dp(100)
  },
  historyTitle: {
    height: px2dp(74),
    lineHeight: px2dp(74),
    paddingLeft: px2dp(30),
    color: '#999999'
  },
  setting: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    width: '100%'
  },
  settingItem: {
    backgroundColor: '#ffffff',
    height: px2dp(96),
    lineHeight: px2dp(96),
    marginTop: px2dp(1)
  },
  settingItemIcon: {
    paddingLeft: px2dp(31),
    paddingRight: px2dp(45)
  }
})
